home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Contributions / Angela_Schmidt / Reference / AIFF_CD.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-11-08  |  19.0 KB  |  538 lines

  1. /*
  2. ** AIFF_CD.h - header file defining both chunks of the AIFF-CD standard in C
  3. **             and the standard itself
  4. **
  5. ** $Id: AIFF_CD.h 1.6 1998/11/02 11:52:47 patrick Rel patrick $
  6. **
  7. ** $Log: AIFF_CD.h $
  8. ** Revision 1.6  1998/11/02 11:52:47  patrick
  9. ** added the authors mail address
  10. **
  11. ** Revision 1.5  1998/11/02 11:46:02  patrick
  12. ** External filenames are explicitely required to follow the Amiga convations.
  13. ** Added explanation of this convention.
  14. **
  15. ** Revision 1.4  1998/07/02 11:45:56  patrick
  16. ** added RCS logging
  17. **
  18. **
  19. ** Revision 1.3:
  20. **   added example
  21. ** Revision 1.2:
  22. **   added macros to step between ACD_TRInfos
  23. ** Revision 1.1:
  24. **   initial revision
  25. **
  26. ** ©1998 Patrick Ohly, Patrick.Ohly@gmx.de
  27. */
  28.  
  29. #ifndef AIFF_CD_H
  30. #define AIFF_CD_H
  31.  
  32. /*
  33. ** CD-ROM extensions to AIFF[-C] standard
  34. ** ======================================
  35. ** 
  36. ** 1. Introduction
  37. ** ---------------
  38. **
  39. ** The intention of this document is to define an extension to the AIFF and
  40. ** AIFC data file format that allows such files to represent all informations
  41. ** relevant to an audio and mixed-mode CD (data track + audio tracks).
  42. ** 
  43. ** Knowledge about these two standards and IFF are expected. This document uses
  44. ** the same data type notation as in those standards. AIFF is used as a synonym
  45. ** for both AIFF and AIFC from now on.
  46. ** 
  47. ** This documents's main focus are definitely audio CDs. It does not try to
  48. ** represent all possible types of CDs, only those that consist of one session,
  49. ** consecutive audio tracks plus one optional data track at the beginning.
  50. ** ".aiff-cd" and ".aifc-cd" should be used as suffices for this new file
  51. ** format.
  52. ** 
  53. ** The audio tracks are stored in the usual AIFF way and can have any format
  54. ** valid for AIFF. It is up to applications to cope with different number of
  55. ** channels, bits per sample, and frequency correctly.
  56. ** 
  57. ** This approach has the advantage that existing audio applications can access
  58. ** the audio data without any modifications in the program. It has the
  59. ** disadvantage that the audio data has to be copied, too.
  60. ** 
  61. ** Therefore the audio data for each track may alternatively be stored in
  62. ** another file that is only referenced by the AIFF-CD file. The contents of
  63. ** this other file is not defined by this standard.
  64. ** 
  65. ** Applications aware of the CD-ROM extensions may store the following
  66. ** informations:
  67. ** - International Standard Recording Code (ISRC) and other
  68. **   advanced information for some or all tracks
  69. ** - Medium Catalog Number for the CD
  70. ** - Index markers within each track
  71. ** - one data track
  72. ** 
  73. ** These extensions are stored in local chunks within the AIFF
  74. ** form. They are defined in the following chapter. They are illustrated
  75. ** by an example at the end of this document.
  76. ** 
  77. ** 2. Chunk Definitions
  78. ** --------------------
  79. ** 
  80. ** All of these chunks are optional. It is up to an application to use
  81. ** reasonable default values, if necessary. The following data types
  82. ** are used in this standard:
  83. */
  84.  
  85. typedef unsigned long ACD_Block;      /* logical CD block,
  86.                                          1min = 60s, 1s = 75 blocks,
  87.                                          block #0 == 00:02:00 min:sec:frame */
  88. typedef unsigned long ACD_AudioBlock; /* as above, but now relative to beginning
  89.                                          of the audio sample:
  90.                                          block #0 == 0.0 sec of audio sample */
  91. typedef unsigned long ACD_SampleNum;  /* position within an audio sample or
  92.                                          amount of audio data;
  93.                                          this value is independent from the
  94.                                          number of channels, i.e. multiple
  95.                                          samples played in parallel only count
  96.                                          as one sample */
  97. typedef unsigned long ACD_ULONG;      /* 32 bit integer, unsigned */
  98. typedef   signed long ACD_LONG;       /* 32 bit integer, signed */
  99. typedef     ACD_ULONG ACD_ID;
  100.  
  101. /*
  102. ** Some more types as defined in the AIFF standard are used in the
  103. ** definition of chunks. Any definition not allowed in C (variable sized
  104. ** arrays, pstrings, ... ) are excluded using
  105. ** #ifdef ACD_NON_C_DATATYPES
  106. ** ...
  107. ** #endif.
  108. ** Take care to handle those entries in the chunks correctly in your code.
  109. **
  110. ** These are chunks required for AIFF and AIFC. They are included for
  111. ** your convenience only and are explained in the corresponding standards.
  112. */
  113.  
  114. typedef struct {
  115.     unsigned short    exponent;            /* Exponent, bit #15 is sign bit for mantissa */
  116.     unsigned long    mantissa[2];        /* 64 bit mantissa */
  117. } extended;
  118.  
  119. typedef struct
  120. {
  121.     SHORT numChannels;
  122.     ULONG numSampleFrames;
  123.     SHORT sampleSize;
  124.     extended sampleRate;
  125. } AIFF_CommonChunk;
  126.  
  127. typedef struct
  128. {
  129.     SHORT numChannels;
  130.     ULONG numSampleFrames;
  131.     SHORT sampleSize;
  132.     extended sampleRate;
  133.     ULONG compression_ID;
  134. }  AIFC_CommonChunk;
  135.  
  136. typedef struct
  137. {
  138.     ULONG offset;
  139.     ULONG blocksize;
  140. } AIF_SoundData;
  141.  
  142.  
  143. /*
  144. ** 2.1 Track Information
  145. ** ^^^^^^^^^^^^^^^^^^^^^
  146. ** 
  147. ** For each track its source and type can be defined independently. The data can either
  148. ** be contained in the SSND chunk of the AIFF-CD file itself or in the file refered to
  149. ** in the track entry. If an external file is used then it is up to the application to
  150. ** recognize the format. In both cases the relevant data may be some subpart of the
  151. ** source defined by start and length.
  152. */
  153.  
  154.  
  155. #define ACD_TRI_PREAMPHASIZE    (1<<0)    /* audio data was sampled with preamphasize */
  156. #define ACD_TRI_COPYRIGHTED     (1<<1)    /* data has a copyright */
  157. #define ACD_TRI_EXTERNAL        (1<<2)    /* data is stored in an external file */
  158. #define ACD_TRI_PAUSE           (1<<3)    /* last entry in index list marks a pause */
  159.  
  160. typedef struct {
  161.     ACD_ULONG        pause;            /* This number of empty blocks shall be generated
  162.                                           before the track when writing to CD-R; usually 0.
  163.                                           This data will be part of the pregap.             */
  164.     ACD_SampleNum    start;            /* beginning and                                     */
  165.     ACD_SampleNum    length;           /* length of the audio data taken from the source(s) */
  166.     ACD_ULONG        flags;            /* ACD_TRI_#? as defined above */
  167.  
  168.     ACD_ULONG        numIndices;       /* Indices are given relative to the beginning of   
  169.                                           the real audio data of this track (i.e. 'start').
  170.                                           Index #1 always starts at 0 and has to be omitted.
  171.                                           The last entry is the beginning of the index pause
  172.                                           if ACD_TRI_PAUSE is set, otherwise just another index. */
  173.  
  174.     /* Entry may be extended in the future by a variable number of bytes;
  175.        this is the number of bytes appended to this structure at the end in
  176.        reserved[].                                                          */
  177.     ACD_ULONG        numReservedBytes;    /* 0 at the moment */
  178.  
  179.  
  180.     #ifdef ACD_NON_C_DATATYPES
  181.     ACD_AudioBlock indices[];
  182.  
  183.     /* only used with ACD_TRI_EXTERNAL, but always present;
  184.        filename can be absolute or relativ to the
  185.        directory the AIFF-CD file is stored in.
  186.     
  187.        AIFF-CD follows the Amiga filename conventions:
  188.        [[»volume«]:][[»dir«]/]*»filename«
  189.     
  190.        »volume«, »dir« and »filename« are 8 bit characters
  191.        without colon (":") and slash ("/"). Absolute paths
  192.        are specified with the optional volume name followed
  193.        by a colon. The colon alone refers to the root directory
  194.        of the filesystem that contains the AIFF-CD file. The
  195.        usage of the absolute part of the filename on non-Amiga
  196.        systems is not specified.
  197.     
  198.        The path specification is similar to Unix, with only one
  199.        exception: a slash without a preceeding directory name
  200.        refers to the parent directory.
  201.        E.g. "dir1/dir2//file" = "dir1/file"
  202.             "/" = parent directory of current directory
  203.     */
  204.  
  205.     pstring       externalFile[];
  206.  
  207.     byte          reserved[];          /* just skip these bytes if the contents is unknown */
  208.     #endif
  209. } ACD_TRInfo;
  210.  
  211. /*
  212. ** Going from one ACD_TRInfo to the next is a bit tricky because of the
  213. ** variable sized entries at the end. These macros can be used in C to get
  214. ** pointers to the first ACD_TRInfo, all following ones and indices[]/
  215. ** externalFile[]/reserved[].
  216. **
  217. ** ACD_FIRST_TRINFO() expects a pointer to the ACD_TRInfoChunk structures
  218. ** as defined below, including all the data of the chunk. The chunk header
  219. ** has to be part of this data if and only if ACD_CHUNK_HEADER was defined
  220. ** to include it in the C structure, too.
  221. **
  222. ** The same applies to the other macros which expect a pointer to
  223. ** ACD_TRInfo.
  224. */
  225.  
  226. #define ACD_FIRST_TRINFO(tr_infos) \
  227.     ((ACD_TRInfo *) &((ACD_TRInfoChunk *)tr_infos)[1])  /* skip general infos */
  228.  
  229. #define ACD_TRINFO_INDICES(tr_info) \
  230.     ((ULONG *) &((ACD_TRInfo *)tr_info)[1])             /* skip track specific infos of constant length */
  231.  
  232. #define ACD_TRINFO_EXTERNAL(tr_info) \
  233.     ((UBYTE *) &ACD_TRINFO_INDICES(tr_info)[((ACD_TRInfo *)tr_info)->numIndices])
  234.                                                         /* start at indices and skip all of them */
  235.  
  236. #define ACD_TRINFO_NEXT(tr_info) \
  237.     ((ACD_TRInfo *) &ACD_TRINFO_EXTERNAL(tr_info)[ACD_TRINFO_EXTERNAL(tr_info)[0] + \
  238.                                                   ((ACD_TRINFO_EXTERNAL(tr_info)[0] % 2) ? 1 : 2) + \
  239.                                                   ((ACD_TRInfo *)tr_info)->numReservedBytes])
  240.                                                         /* start at external file name,
  241.                                                            skip the name itself,
  242.                                                            the length byte and the optional pad byte
  243.                                                            and finally the reserved bytes */
  244.  
  245.  
  246. /*
  247. ** The different TRInfos are gathered in one obligatory chunk:
  248. */
  249.  
  250. #define ACD_TRINFOID 'TRIF'
  251.  
  252. typedef struct {
  253. #ifdef ACD_CHUNK_HEADER
  254.     ACD_ID           ckID;             /* 'TRIF' */
  255.     ACD_LONG         ckDataSize;
  256. #endif
  257.  
  258.     ULONG            version;          /* 1 at the moment - don't accept versions you don't know,
  259.                                           any other chunk might have changed */
  260.     ACD_ULONG        firstTrackNum;    /* the first track number can be chosen, the following
  261.                                           once increase in steps of one */
  262.     ACD_ULONG        numTRInfos;
  263.     #ifdef ACD_NON_C_DATATYPES
  264.     TRInfo         TRInfos[];
  265.     #endif
  266. } ACD_TRInfoChunk;
  267.  
  268.  
  269. /*
  270. ** 2.2 ISRC
  271. ** ^^^^^^^^
  272. ** 
  273. ** For each track at most one ISRC can be specified. Tracks are referenced by
  274. ** their index in the track info array, not by what they would have on CD.
  275. ** Only some characters are allowed for the four components of an ISRC. Each
  276. ** component has to consist of exactly the right number of characters.
  277. */
  278.  
  279. typedef char ACD_AZASCII;    /* ASCII value of characters A-Z */
  280. typedef char ACD_AZ09ASCII;  /* ASCII value of characters 0-9 and A-Z */
  281. typedef char ACD_09ASCII;    /* ASCII value of characters 0-9 */
  282.  
  283. typedef struct {
  284.     ACD_ULONG        track;            /* the same as in the CDMarkers */
  285.     ACD_AZASCII      country[2];       /* country code */
  286.     ACD_AZ09ASCII    owner[3];         /* owner code */
  287.     ACD_09ASCII      year[2];          /* year of recording */
  288.     ACD_09ASCII      serial[5];        /* serial number assigned by owner */
  289. } ACD_ISRC;
  290.  
  291. /*
  292. ** The different ISRCs are gathered in one optional chunk.
  293. ** Not every track must have an ISRC, but entries have to be
  294. ** sorted on the track number in increasing order.
  295. */
  296.  
  297. #define ACD_ISRCID 'ISRC'
  298.  
  299. typedef struct {
  300. #ifdef ACD_CHUNK_HEADER
  301.     ACD_ID           ckID;             /* 'ISRC' */
  302.     ACD_LONG         ckDataSize;
  303. #endif
  304.  
  305.     ACD_ULONG           numISRCs;
  306.     #ifdef ACD_NON_C_DATATYPES 
  307.     ISRC           ISRCs[];
  308.     #endif
  309. } ACD_ISRCChunk;
  310.  
  311.  
  312. /*
  313. ** 2.3 Medium Catalog Number
  314. ** ^^^^^^^^^^^^^^^^^^^^^^^^^
  315. ** 
  316. ** This optional chunk stores the UPC/EAN number of the CD. The same rules
  317. ** for valid characters and length as for ISRC apply.
  318. */
  319.  
  320. #define ACD_MCNID 'MCNU'
  321.  
  322. typedef struct {
  323. #ifdef ACD_CHUNK_HEADER
  324.     ACD_ID           ckID;             /* 'MCNU' */
  325.     ACD_LONG         ckDataSize;
  326. #endif
  327.  
  328.     ACD_09ASCII      MCNum[13];        /* Medium Catalog Number */
  329.     ACD_09ASCII      pad;
  330. } ACD_MCNChunk;
  331.  
  332.  
  333. /*
  334. ** 2.4 Data Track
  335. ** ^^^^^^^^^^^^^^
  336. ** 
  337. ** This optional chunk is not relevant for audio applications. It is used
  338. ** by CD writer software to allow the user to store the image of a
  339. ** complete CD in one file. An audio application should copy this chunk
  340. ** unchanged when writing back a AIFF-CD file or warn the user if it is
  341. ** not able to do so.
  342. ** 
  343. ** Different types of data can be stored and different data formats are
  344. ** allowed. More types may be defined latter. An applications should be
  345. ** prepared to issue a meaningful warning (perhaps using the data type and
  346. ** format names specified in the chunk) if unknown or unsupported data is
  347. ** found.
  348. */
  349.  
  350. typedef enum {
  351.     ACD_MODE1,       /* CD-ROM mode 1 (block size 2048 bytes) */
  352.     ACD_MODE2,       /* CD-ROM mode 2 (2336 bytes) */
  353.     ACD_MODE2_FORM1, /* XA mode 2, form 1 (2048 bytes) */
  354.     ACD_MODE2_FORM2  /* XA mode 2, form 2 (2324 bytes) */
  355. } ACD_DataType;
  356.  
  357. typedef enum {
  358.     ACD_DF_COOKED,   /* only user data with block size as specified above */
  359.     ACD_DF_RAW       /* complete block of 2352 bytes, containing user data,
  360.                        sync, (sub) header and EDC/EDD as specified in the MMC
  361.                        standard; not scrambled */
  362. } ACD_DataFormat;
  363.  
  364. /*
  365. ** These enumerations have the following English names:
  366. */
  367.  
  368. #ifdef ACD_NAMES
  369. char *ACD_TypeNames[] = {
  370.     "Mode 1",
  371.     "Mode 2",
  372.     "Mode 2, Form 1",
  373.     "Mode 2, Form 2"
  374. };
  375.  
  376. char *ACD_FormatNames[] = {
  377.     "cooked",
  378.     "raw"
  379. };
  380. #endif
  381.  
  382. /*
  383. ** The data track contains data with the block size specified by type and
  384. ** format. This data is placed in a chunk on its own to allow seperate
  385. ** writing of the data and the control information. The number of blocks
  386. ** is deduced from the length of this chunk and the block size.
  387. ** 
  388. ** The track starts on the CD at a specific logical CD
  389. ** block ("startBlock") and must not be relocated without appropriate warnings or
  390. ** transformations. The data may contain some blocks ("preGapLen") that are
  391. ** already part of the pregap between the data track and the following audio
  392. ** track. This pregap is described by the logical CD block number where the
  393. ** the second, audio part starts ("audioPregapStart") and the logical CD block
  394. ** number where the audio data is placed ("audioStart"):
  395. ** 
  396. ** # trackType/Format data in the data chunk
  397. ** +     "      "       "  that has to be generated
  398. ** * audio data as defined by the track infos chunk
  399. **   (a pause requested for the first audio track is valid and
  400. **    moves the audioStart)
  401. ** - audio data that has to be generated
  402. ** 
  403. ** #####################################+++------------------****************
  404. ** |                   |               |   |                 |
  405. ** startBlock           <- preGapLen ->    audioPregapStart  audioStart
  406. ** <--- data track ---> <---       pregap (index 0)      ---> <-- audio track
  407. ** 
  408. ** All these values are placed in this chunk:
  409. */
  410.  
  411. #define ACD_DATATRACKINFOID 'CDTI'
  412.  
  413. typedef struct {
  414. #ifdef ACD_CHUNK_HEADER
  415.     ACD_ID           ckID;             /* 'CDTI' */
  416.     ACD_LONG         ckDataSize;
  417. #endif
  418.  
  419.     ACD_DataType     trackType;
  420.     ACD_DataFormat   trackFormat;
  421.     ACD_Block        startBlock;       /* usually #0 */
  422.     ACD_ULONG        preGapLen;          
  423.     ACD_Block        audioPregapStart; /* >= startBlock + number of blocks */
  424.     ACD_Block        audioStart;       /* > audioPregapStart */
  425.  
  426.     ACD_ULONG        flags;            /* none defined at the moment */
  427.     ACD_ULONG        reserved[4];      /* has to be set to 0 */
  428.  
  429.     #ifdef ACD_NON_C_DATATYPES
  430.     pstring       trackTypeName;       /* from TypeNames   */
  431.     pstring       dataFormatName;      /* from FormatNames */
  432.     #endif
  433.  
  434. } ACD_DataTrackInfoChunk;
  435.  
  436.  
  437. /*
  438. ** This is the chunk for the track data itself. It has to be present if
  439. ** the data track is present.
  440. */
  441.  
  442. #define ACD_DATATRACKDATAID 'CDDT'
  443.  
  444. #ifdef ACD_NON_C_DATATYPES
  445. typedef struct
  446. {
  447. #ifdef ACD_CHUNK_HEADER
  448.     ACD_ID           ckID;             /* 'CDDT' */
  449.     ACD_LONG         ckDataSize;
  450. #endif
  451.  
  452.     /* pure data - number of blocks can be calculated from
  453.                    ckDataSize and block size               */
  454.     char          trackData[];
  455. } ACD_DataTrackDataChunk;
  456. #endif
  457.  
  458. /*
  459. ** Future CD alike media (e.g. DVD) might contain too much blocks to count the
  460. ** number of bytes in ckDataSize. This document does not try to solve this
  461. ** problem, because the audio data storable in AIFF itself is already limited
  462. ** the same way.
  463. */
  464.  
  465.  
  466. /*
  467. ** Appendix I: example AIFF-CD file
  468. **
  469. ** This hex dump describes an audio CD with
  470. ** a medium catalog number ("9876543219876") and
  471. ** two tracks:
  472. ** 1. audio data without preamphasize,
  473. **    starting at CD block #32, length 10 seconds,
  474. **    no ISRC, indices relativ to track start:
  475. **    #1: 0 seconds (by definition of a track)
  476. **    #2: 2 seconds
  477. **    #3: 5 seconds
  478. **    no index pause
  479. ** 2. audio data with preamphasize,
  480. **    starting at CD block #782, length 10 seconds,
  481. **    ISRC "UK POH 98 12345", indices:
  482. **    #1: 0 seconds (s.o.)
  483. **    index pause: 8 seconds
  484. **
  485. ** AIFF form chunk:
  486. **    464F524D 0035D5F4 41494646
  487. **    "FORM"   length   "AIFF"
  488. ** common chunk:
  489. **    434F4D4D 00000012
  490. **    "COMM"   length
  491. **    0002         - 2 channels
  492. **    000D7550     - 882000 sample frames = 20 seconds
  493. **    0010         - 16 bit sampling size
  494. **    400EAC44 00000000 0000 - frequency (see AIFF standard)
  495. ** track infos chunk:
  496. **    54524946 0000004C
  497. **    "TRIF"   length
  498. **    00000001     - version 1 of AIFF-CD
  499. **    00000001     - number of first track on CD
  500. **    00000002     - two track in the file
  501. **    track infos for track #1:
  502. **    00000020     - prepend pause of 32 blocks
  503. **    00000000     - start at sample frame #0 in SSND chunk
  504. **    0006BAA8     - 441000 sample frames long = 10 seconds
  505. **    00000002     - flags: ACD_TRI_COPYRIGHTED
  506. **    00000002     - two indices in addition to the obligatory one at the beginning
  507. **    00000000     - number of reserved bytes: none
  508. **    00000096     - indices at track block #150 = 2 seconds
  509. **    00000177     - and at track block #375 = 5 seconds
  510. **                 - _no_ index pause (ACD_TRI_PAUSE not set)
  511. **    0000         - empty filename (length 0 + pad byte)
  512. **    no reserved bytes, track infos for track #2:
  513. **    00000000     - no pause
  514. **    0006BAA8     - start at sample frame #441000 = 10 seconds
  515. **    0006BAA8     - 441000 sample frames long = 10 seconds
  516. **    0000000B     - flags: ACD_TRI_PREAMPHASIZE, ACD_TRI_COPYRIGHTED, ACD_TRI_PAUSE
  517. **    00000001     - one index marker
  518. **    00000000     - number of reserved bytes: none
  519. **    00000258     - index _pause_ (ACD_TRI_PAUSE is set) at #600 = 8 seconds
  520. **    0000         - empty filename
  521. ** medium catalog number chunk:
  522. **    4D434E55 0000000E 39383736353433323139383736 00
  523. **    "MCNU"   length   "9876543219876"            pad byte
  524. ** ISRC chunk:
  525. **    49535243 00000014
  526. **    "ISRC"   length
  527. **    00000001     - one ISRC:
  528. **    00000001     - track _index_ in infos array, i.e. ISRC is for track #2
  529. **    554B 4F484C 3938 3132333435
  530. **    "UK  OHL    98   12345"
  531. ** sound chunk:
  532. **     53534E44 0035D548
  533. **     "SSND"   length
  534. **     [3528008 bytes of audio data follow]
  535. */
  536.  
  537. #endif /* AIFF_CD_H */
  538.